package com.example.isoftlangchainai.responseformat;

import com.fasterxml.jackson.databind.ObjectMapper;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.request.ResponseFormat;
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
import dev.langchain4j.model.chat.request.json.JsonSchema;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import static dev.langchain4j.model.chat.Capability.RESPONSE_FORMAT_JSON_SCHEMA;
import static dev.langchain4j.model.chat.request.ResponseFormatType.JSON;

/**
 * @Description:
 * @Date :2025/7/14 16:41
 * @Author :chenjun
 */
@RestController
@RequestMapping("/format")
public class FormatChatController {
    @Value("${langchain4j.open-ai.chat-model.api-key}")
    protected String apikey;
    @Value("${langchain4j.open-ai.chat-model.model-name}")
    protected String modelName;
    @Value("${langchain4j.open-ai.chat-model.base-url}")
    protected String baseUrl;

    /**
     *
     * [描述]: 1基于JsonObjectSchema实现结构化输出
     */
    @GetMapping ("/chat")
    public String getChat() {
        String output = "抱歉,转换失败.";
        try {
            ResponseFormat responseFormat = ResponseFormat.builder()
                    .type(JSON) // type can be either TEXT (default) or JSON
                    .jsonSchema(JsonSchema.builder()
                            .name("Person") // OpenAI requires specifying the name for the schema
                            .rootElement(JsonObjectSchema.builder() // see [1] below
                                    .addStringProperty("name")
                                    .addIntegerProperty("age")
                                    .addNumberProperty("height")
                                    .addBooleanProperty("married")
                                    .required("name", "age", "height", "married") // see [2] below
                                    .build())
                            .build())
                    .build();

            UserMessage userMessage = UserMessage.from("""
                John is 42 years old and lives an independent life.
                He stands 1.75 meters tall and carries himself with confidence.
                Currently unmarried, he enjoys the freedom to focus on his personal goals and interests.
                """);

            ChatRequest chatRequest = ChatRequest.builder()
                    .responseFormat(responseFormat)
                    .messages(userMessage)
                    .build();

            ChatModel chatModel = OpenAiChatModel.builder()
                    .baseUrl(baseUrl)
                    .apiKey(apikey)
                    .modelName(modelName)
                    .logRequests(true)
                    .logResponses(true)
                    .build();

            ChatResponse chatResponse = chatModel.chat(chatRequest);
            output = chatResponse.aiMessage().text();
            System.out.println("************************格式化************************:" + output); // {"name":"John","age":42,"height":1.75,"married":false}

            //将 {"name":"John","age":42,"height":1.75,"married":false} 转换成Person对象
            ObjectMapper objectMapper = new ObjectMapper();
            Person person = objectMapper.readValue(output, Person.class);
            System.out.println("************************转换成Person对象**************:" + person); // {"name":"John","age":42,"height":1.75,"married":false}
        }catch (Exception e) {
            System.out.println("异常,原因:" + e.getMessage());
        }
        return output;
    }

    /**
     *
     * [描述]:2 AI Services实现结构化输出
     */
    interface PersonExtractor {
        Person extractPersonFrom(String text);
    }

    @GetMapping ("/aichat")
    public String aichat() {
        String output = "抱歉,转换失败.";
        try {
            ChatModel chatModel = OpenAiChatModel.builder()
                    .baseUrl(baseUrl)
                    .apiKey(apikey)
                    .modelName(modelName)
                    .supportedCapabilities(RESPONSE_FORMAT_JSON_SCHEMA) // see [2] below
                    .strictJsonSchema(false) // see [2] below
                    .logRequests(true)
                    .logResponses(true)
                    .build();

            PersonExtractor personExtractor = AiServices.create(PersonExtractor.class, chatModel); // see [1] below
            String text = """
                John is 42 years old and lives an independent life.
                He stands 1.75 meters tall and carries himself with confidence.
                Currently unmarried, he enjoys the freedom to focus on his personal goals and interests.
                """;

            Person person = personExtractor.extractPersonFrom(text);
            System.out.println("************************转换成Person对象**************:" + person); // {"name":"John","age":42,"height":1.75,"married":false}
        }catch (Exception e) {
            System.out.println("异常,原因:" + e.getMessage());
        }
        return output;
    }
}
